package com.kantboot.global.auth.util;

import com.kantboot.global.auth.annotation.AdminController;
import com.kantboot.global.auth.model.vo.AuthVO;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;


public class AuthUtil {

    /**
     * 获取所有com.kantboot包下带有@AdminController注解的类
     */
    public static List<Class<?>> getAdminControllers() {
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(ClasspathHelper.forPackage("com.kantboot"))
                .setScanners(new SubTypesScanner(false)));

        var allClasses = reflections.getSubTypesOf(Object.class);
        List<Class<?>> adminControllers = new ArrayList<>();

        for (Class<?> clazz : allClasses) {
            if (clazz.isAnnotationPresent(AdminController.class)) {
                adminControllers.add(clazz);
            }
        }

        return adminControllers;
    }

    /**
     * 获取类上RequestMapping的值
     */
    public static String getRequestMapping(Class<?> clazz) {
        // 判断是否有RequestMapping注解
        if (clazz.isAnnotationPresent(org.springframework.web.bind.annotation.RequestMapping.class)) {
            org.springframework.web.bind.annotation.RequestMapping requestMapping = clazz.getAnnotation(org.springframework.web.bind.annotation.RequestMapping.class);
            return requestMapping.value()[0];
        }
        // 判断是否有PostMapping注解
        if (clazz.isAnnotationPresent(org.springframework.web.bind.annotation.PostMapping.class)) {
            org.springframework.web.bind.annotation.PostMapping postMapping = clazz.getAnnotation(org.springframework.web.bind.annotation.PostMapping.class);
            return postMapping.value()[0];
        }
        // 判断是否有GetMapping注解
        if (clazz.isAnnotationPresent(org.springframework.web.bind.annotation.GetMapping.class)) {
            org.springframework.web.bind.annotation.GetMapping getMapping = clazz.getAnnotation(org.springframework.web.bind.annotation.GetMapping.class);
            return getMapping.value()[0];
        }
        // 判断是否有PutMapping注解
        if (clazz.isAnnotationPresent(org.springframework.web.bind.annotation.PutMapping.class)) {
            org.springframework.web.bind.annotation.PutMapping putMapping = clazz.getAnnotation(org.springframework.web.bind.annotation.PutMapping.class);
            return putMapping.value()[0];
        }
        // 判断是否有DeleteMapping注解
        if (clazz.isAnnotationPresent(org.springframework.web.bind.annotation.DeleteMapping.class)) {
            org.springframework.web.bind.annotation.DeleteMapping deleteMapping = clazz.getAnnotation(org.springframework.web.bind.annotation.DeleteMapping.class);
            return deleteMapping.value()[0];
        }
        // 判断是否有PatchMapping注解
        if (clazz.isAnnotationPresent(org.springframework.web.bind.annotation.PatchMapping.class)) {
            org.springframework.web.bind.annotation.PatchMapping patchMapping = clazz.getAnnotation(org.springframework.web.bind.annotation.PatchMapping.class);
            return patchMapping.value()[0];
        }
        // 都没有则返回空字符串
        return "";
    }

    /**
     * 获取方法上的RequestMapping的值
     * @param method 方法
     * @return String
     */
    public static String getMethodRequestMapping(Method method) {
        // 判断是否有RequestMapping注解
        if (method.isAnnotationPresent(org.springframework.web.bind.annotation.RequestMapping.class)) {
            org.springframework.web.bind.annotation.RequestMapping requestMapping = method.getAnnotation(org.springframework.web.bind.annotation.RequestMapping.class);
            return requestMapping.value()[0];
        }
        // 判断是否有PostMapping注解
        if (method.isAnnotationPresent(org.springframework.web.bind.annotation.PostMapping.class)) {
            org.springframework.web.bind.annotation.PostMapping postMapping = method.getAnnotation(org.springframework.web.bind.annotation.PostMapping.class);
            return postMapping.value()[0];
        }
        // 判断是否有GetMapping注解
        if (method.isAnnotationPresent(org.springframework.web.bind.annotation.GetMapping.class)) {
            org.springframework.web.bind.annotation.GetMapping getMapping = method.getAnnotation(org.springframework.web.bind.annotation.GetMapping.class);
            return getMapping.value()[0];
        }
        // 判断是否有PutMapping注解
        if (method.isAnnotationPresent(org.springframework.web.bind.annotation.PutMapping.class)) {
            org.springframework.web.bind.annotation.PutMapping putMapping = method.getAnnotation(org.springframework.web.bind.annotation.PutMapping.class);
            return putMapping.value()[0];
        }
        // 判断是否有DeleteMapping注解
        if (method.isAnnotationPresent(org.springframework.web.bind.annotation.DeleteMapping.class)) {
            org.springframework.web.bind.annotation.DeleteMapping deleteMapping = method.getAnnotation(org.springframework.web.bind.annotation.DeleteMapping.class);
            return deleteMapping.value()[0];
        }
        // 判断是否有PatchMapping注解
        if (method.isAnnotationPresent(org.springframework.web.bind.annotation.PatchMapping.class)) {
            org.springframework.web.bind.annotation.PatchMapping patchMapping = method.getAnnotation(org.springframework.web.bind.annotation.PatchMapping.class);
            return patchMapping.value()[0];
        }
        // 都没有则返回空字符串
        return "";
    }

    /**
     * 获取类上所有时请求的方法
     * @param clazz 类
     * @return List<Method>
     */
    public static List<Method> getRequestMethods(Class<?> clazz) {
        Method[] methods = clazz.getMethods();
        List<Method> requestMethods = new ArrayList<>();
        for (Method method : methods) {
            String requestMapping = getMethodRequestMapping(method);
            if (!"".equals(requestMapping)) {
                requestMethods.add(method);
            }
        }
        return requestMethods;
    }

    /**
     * 获取类上@AdminController注解的值
     */
    public static AuthVO getAdminControllerAuth(Class<?> clazz) {
        AdminController adminController = clazz.getAnnotation(AdminController.class);
        return new AuthVO().setName(adminController.name()).setCode(adminController.code()).setPriority(adminController.priority());
    }


}
